#include "msc_device.h"
#include "esp_log.h"
#include "usb/usb_host.h"
#include "driver/gpio.h"
#include <esp_vfs_fat.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "freertos/projdefs.h"
#include "msc_host.h"
#include <string.h>
#define USB_DISCONNECT_PIN  GPIO_NUM_10
#define TAG "msc_device"

typedef enum {
    HOST_NO_CLIENT = 0x1,
    HOST_ALL_FREE = 0x2,
    DEVICE_CONNECTED = 0x4,
    DEVICE_DISCONNECTED = 0x8,
    DEVICE_ADDRESS_MASK = 0xFF0,
} app_event_t;



static msc_device_t g_msc_device;

static msc_device_state_callback g_state_callback = NULL;

void msc_device_set_state_callback(msc_device_state_callback cb)
{
    g_state_callback = cb;
}

static void msc_event_cb(const msc_host_event_t *event, void *arg)
{
    if (event->event == MSC_DEVICE_CONNECTED) {
        ESP_LOGI(TAG, "MSC device connected");
        xEventGroupSetBits(g_msc_device.event_group, 
                         DEVICE_CONNECTED | (event->device.address << 4));
    } else if (event->event == MSC_DEVICE_DISCONNECTED) {
        xEventGroupSetBits(g_msc_device.event_group, DEVICE_DISCONNECTED);
        ESP_LOGI(TAG, "MSC device disconnected");
    }
}

static void handle_usb_events(void *args)
{
    while (1) {
        uint32_t event_flags;
        usb_host_lib_handle_events(portMAX_DELAY, &event_flags);

        if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) {
            usb_host_device_free_all();
            xEventGroupSetBits(g_msc_device.event_group, HOST_NO_CLIENT);
        }
        if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) {
            xEventGroupSetBits(g_msc_device.event_group, HOST_ALL_FREE);
        }
    }

    vTaskDelete(NULL);
}

static void msc_device_task(void *arg)
{
    msc_device_t *msc = (msc_device_t *)arg;
    
    while (msc->running) {
        // 等待设备连接
        uint8_t device_address = msc_device_wait_connect();
        if (!msc->running) break;

        // 安装设备
        if (msc_host_install_device(device_address, &msc->device) != ESP_OK) {
            ESP_LOGE(TAG, "Failed to install MSC device");
            continue;
        }

        // 注册VFS
        const esp_vfs_fat_mount_config_t mount_config = {
            .format_if_mount_failed = false,
            .max_files = 3,
            .allocation_unit_size = 1024,
        };

        // 添加设备状态检查
        bool device_ok = true;
        
        // 注册VFS前先确保之前的资源已清理
        if (msc->vfs_handle != NULL) {
            msc_host_vfs_unregister(msc->vfs_handle);
            msc->vfs_handle = NULL;
        }

        msc_host_get_device_info(msc->device, &msc->g_info);

        if (msc_host_vfs_register(msc->device, "/usb", &mount_config, &msc->vfs_handle) != ESP_OK) {
            ESP_LOGE(TAG, "Failed to register VFS");
            msc_host_uninstall_device(msc->device);
            vTaskDelay(pdMS_TO_TICKS(1000)); // 添加延时避免立即重试
            continue;
        }
        
        if (g_state_callback) {
            g_state_callback(true);
        }

        // 改进设备事件处理循环
        while (device_ok && msc->running) {
            EventBits_t bits = xEventGroupWaitBits(
                msc->event_group,
                DEVICE_DISCONNECTED,
                pdTRUE,
                pdTRUE,
                pdMS_TO_TICKS(1000)
            );

            if (bits & DEVICE_DISCONNECTED) {
                break;
            }
        }

        if (g_state_callback) {
            g_state_callback(false);
        }
        
        if (msc->vfs_handle) {
            ESP_LOGI(TAG, "Unregistering VFS");
            msc_host_vfs_unregister(msc->vfs_handle);
            msc->vfs_handle = NULL;
        }
        
        if (msc->device) {
            ESP_LOGI(TAG, "Uninstalling device");
            msc_host_uninstall_device(msc->device);
            msc->device = NULL;
        }

        // 添加短暂延时，避免立即重新检测
        vTaskDelay(pdMS_TO_TICKS(500));
    }

    vTaskDelete(NULL);
}

int msc_device_init(void)
{
    // 初始化全局变量
    memset(&g_msc_device, 0, sizeof(msc_device_t));
    
    // 配置GPIO
    const gpio_config_t input_pin = {
        .pin_bit_mask = BIT64(USB_DISCONNECT_PIN),
        .mode = GPIO_MODE_INPUT,
        .pull_up_en = GPIO_PULLUP_ENABLE,
    };
    ESP_ERROR_CHECK(gpio_config(&input_pin));

    // 创建事件组
    g_msc_device.event_group = xEventGroupCreate();
    if (!g_msc_device.event_group) {
        return -1;
    }

    // 初始化USB主机
    const usb_host_config_t host_config = {
        .intr_flags = ESP_INTR_FLAG_LEVEL1
    };
    ESP_ERROR_CHECK(usb_host_install(&host_config));

    // 创建USB事件处理任务
    BaseType_t task_created = xTaskCreate(handle_usb_events, "usb_events", 
                                        2048, NULL, 2, NULL);
    if (!task_created) {
        vEventGroupDelete(g_msc_device.event_group);
        return -1;
    }

    // 初始化MSC驱动
    const msc_host_driver_config_t msc_config = {
        .create_backround_task = true,
        .task_priority = 5,
        .stack_size = 2048,
        .callback = msc_event_cb,
    };
    ESP_ERROR_CHECK(msc_host_install(&msc_config));

    // 启动MSC设备处理任务
    g_msc_device.running = true;
    task_created = xTaskCreate(msc_device_task, "msc_task", 4096, 
                             &g_msc_device, 5, &g_msc_device.task_handle);
    if (!task_created) {
        msc_host_uninstall();
        vEventGroupDelete(g_msc_device.event_group);
        return -1;
    }

    return 0;
}

uint8_t msc_device_wait_connect(void)
{
    EventBits_t event = xEventGroupWaitBits(g_msc_device.event_group, 
                                          DEVICE_CONNECTED | DEVICE_ADDRESS_MASK,
                                          pdTRUE, pdFALSE, portMAX_DELAY);
    return (event & DEVICE_ADDRESS_MASK) >> 4;
}

int msc_device_register_vfs(msc_host_device_handle_t device, const char *mount_point)
{
    const esp_vfs_fat_mount_config_t mount_config = {
        .format_if_mount_failed = false,
        .max_files = 3,
        .allocation_unit_size = 1024,
    };
    return msc_host_vfs_register(device, mount_point, &mount_config, &g_msc_device.vfs_handle);
}

void msc_device_process_events(void)
{
    while (!xEventGroupWaitBits(g_msc_device.event_group, DEVICE_DISCONNECTED, pdTRUE, pdTRUE, 200)) {
        // 处理其他事件
    }
}

void msc_device_get_info(msc_host_device_info_t *info)
{
    memcpy(info, &g_msc_device.g_info, sizeof(msc_host_device_info_t));
}

void msc_device_deinit(void)
{
    // 停止MSC任务
    g_msc_device.running = false;
    if (g_msc_device.task_handle) {
        xTaskNotify(g_msc_device.task_handle, 0, eNoAction);
        while (eTaskGetState(g_msc_device.task_handle) != eDeleted) {
            vTaskDelay(pdMS_TO_TICKS(10));
        }
    }

    // 卸载MSC驱动
    msc_host_uninstall();
    
    // 等待USB主机清理完成
    xEventGroupWaitBits(g_msc_device.event_group, HOST_NO_CLIENT | HOST_ALL_FREE, 
                       pdTRUE, pdTRUE, portMAX_DELAY);
    
    // 卸载USB主机
    usb_host_uninstall();
    
    // 删除事件组
    if (g_msc_device.event_group) {
        vEventGroupDelete(g_msc_device.event_group);
        g_msc_device.event_group = NULL;
    }
}
